enum ContentType {
  json = 'application/json;charset=UTF-8',
  form = 'application/x-www-form-urlencoded; charset=UTF-8'
}

enum HttpMethod {
  get = 'GET',
  post = 'POST',
  put = 'PUT',
  patch = 'PATCH',
  delete = 'DELETE'
}

interface IHeader {
  'Content-Type'?: string
  'X-Requested-With'?: string
  token?: string

  [propName: string]: any
}

interface RequestConfig {
  body?: any
  method?: string
  headers?: IHeader
  token?: string
  'Content-Type'?: string
}

const myFetch = (url: string, config?: RequestConfig) => {
  return new Promise(async (resolve, reject) => {
    let promise: Response, contentType: string

    if (config?.['Content-Type'] !== undefined) {
      contentType = config['Content-Type']
    } else if (config?.method === HttpMethod.post) {
      contentType = ContentType.form
    } else {
      contentType = ContentType.json
    }

    const parseResult = async (res: Response) => {
      const contentType = res.headers.get('Content-Type')
      if (contentType) {
        if (contentType.indexOf('json') !== -1) return await res.json()
        if (contentType.indexOf('text') !== -1) return await res.text()
        if (contentType.indexOf('form') !== -1) return await res.formData()
        if (contentType.indexOf('video') !== -1) return await res.blob()
      }
      return res.text()
    }

    const handleResult = async (res: Response) => {
      const result = await parseResult(res)
      if (res.ok) return result
    }

    // const requestUrl = (baseUrl + url).replace('//', '/')
    const requestUrl = url
    const headers: Headers = new Headers({
      // 	config?.token === undefined
      // 		? getLocalStorage('token')
      // 		: config.token,
      // 'Content-Type': contentType,
    } as IHeader)

    const requestConfig: RequestInit = {
      headers,
      mode: 'no-cors',
      credentials: 'include'
    }

    try {
      if (!config?.method || config.method === HttpMethod.get) {
        promise = await fetch(requestUrl, {
          ...requestConfig
        })
      } else if (config.method === HttpMethod.post) {
        promise = await fetch(requestUrl, {
          body: JSON.stringify(config.body),
          method: HttpMethod.post,
          ...requestConfig
        })
      } else {
        promise = await fetch(requestUrl, {
          body: JSON.stringify(config.body),
          method: config.method,
          ...requestConfig
        })
      }
      resolve(handleResult(promise))
    } catch (err) {
      console.error('fetch error!', err)
      reject(err)
    }
  })
}

export default myFetch
